Android Architecture Components & Room Database - Topic 5 Summary
1. Introduction to Android Architecture Components (AAC)
AAC provides libraries to help developers build robust, testable, and maintainable Android apps following best architecture practices.
Why Use AAC?
- Reduces boilerplate code
- Encourages recommended app architecture
- Makes apps more testable
- Improves code maintainability
- Fewer dependencies
- Clear separation of concerns
Core Architecture Principles
- UI Layer: Displays data and forwards user events
- ViewModel Layer: Holds data needed for UI, survives configuration changes
- Repository Layer: Single source of truth for all app data
- Data Layer: Manages local and remote data sources
2. ViewModel
ViewModel: Provides data for UI components and survives configuration changes (e.g., screen rotation).
Key Features:
- Survives configuration changes
- Provides data to UI
- Can be shared between fragments
- Part of AndroidX lifecycle library
Restaurant Analogy
Customer (UI) → Orders food
Server (ViewModel) → Takes order to kitchen
Chefs (Repository) → Prepare the meal
Kitchen (Data Sources) → Has ingredients and recipes
ViewModel Implementation
public class MyViewModel extends ViewModel {
private MutableLiveData myData = new MutableLiveData<>();
public void loadData() {
// Load data from repository
myData.postValue("Data loaded");
}
public LiveData getData() {
return myData;
}
}
ViewModel Benefits:
- Keeps UI independent of lifecycle changes
- Separates data management from UI
- Makes UI more maintainable and testable
3. Repository Pattern
Repository: Best practice pattern (not part of AAC libraries) that provides single, clean API to app data.
Key Responsibilities:
- Fetch data from multiple sources
- Cache data appropriately
- Handle data synchronization
- Provide clean API to ViewModel
Multiple Data Sources
Repository can manage:
- Local database (Room)
- Network API calls
- Cache data
- Device preferences
Repository Implementation
public class WordRepository {
private WordDao wordDao;
private LiveData> allWords;
public WordRepository(Application application) {
WordRoomDatabase db = WordRoomDatabase.getDatabase(application);
wordDao = db.wordDao();
allWords = wordDao.getAllWords();
}
public LiveData> getAllWords() {
return allWords;
}
public void insert(Word word) {
WordRoomDatabase.databaseWriteExecutor.execute(() -> {
wordDao.insert(word);
});
}
}
4. Room Database
Room: Robust SQL object mapping library that simplifies SQLite database usage in Android apps.
Key Features:
- Generates SQLite code automatically
- Provides simple API for database operations
- Reduces boilerplate code
- Thread-safe operations
- Compile-time SQL validation
Room Architecture
- Entity: Defines database table schema
- DAO: Provides methods for database access
- Database: Creates and manages database instance
Room Components
| Component |
Purpose |
Example |
| Entity |
Defines database table schema |
Java/Kotlin class with @Entity annotation |
| DAO |
Provides database access methods |
Interface with @Query, @Insert, @Update, @Delete annotations |
| Database |
Creates and manages database instance |
Abstract class extending RoomDatabase |
4.1 Entity
Entity: Represents a database table row. Each instance = one row.
Key Annotations:
@Entity: Marks class as database entity
@PrimaryKey: Identifies primary key column
@ColumnInfo: Customizes column names
@NonNull: Marks field as mandatory
Entity Example
@Entity(tableName = "words")
public class Word {
@PrimaryKey(autoGenerate = true)
private int id;
@ColumnInfo(name = "word")
private String word;
@NonNull
public String getWord() {
return this.word;
}
// Getters and setters
}
Entity Table Representation
| Column |
Type |
Description |
| id |
INTEGER |
Primary key (auto-increment) |
| word |
TEXT |
User's word |
4.2 DAO (Data Access Object)
DAO: Interface that defines database access methods using Room annotations.
Key Annotations:
@Insert: Insert entities
@Update: Update entities
@Delete: Delete entities
@Query: Custom SQL queries
DAO Example
@Dao
public interface WordDao {
@Insert
void insert(Word word);
@Update
void update(Word word);
@Delete
void delete(Word word);
@Query("DELETE FROM words")
void deleteAll();
@Query("SELECT * FROM words ORDER BY word ASC")
LiveData> getAllWords();
@Query("SELECT * FROM words WHERE word LIKE :word")
List findWord(String word);
}
4.3 Database
Database: Abstract class that serves as the main access point to your app's persisted data.
Key Features:
- Singleton pattern implementation
- Defines entities and DAOs
- Provides access to database
Database Example
@Database(entities = {Word.class}, version = 1)
public abstract class WordRoomDatabase extends RoomDatabase {
public abstract WordDao wordDao();
private static volatile WordRoomDatabase INSTANCE;
private static final int NUMBER_OF_THREADS = 4;
static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
public static WordRoomDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (WordRoomDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(
context.getApplicationContext(),
WordRoomDatabase.class,
"word_database"
).build();
}
}
}
return INSTANCE;
}
}
5. Lifecycle-Aware Components
Lifecycle-Aware Components: Components that automatically adjust behavior based on lifecycle state of activity or fragment.
Key Benefits:
- Prevents memory leaks
- Automatically handles lifecycle events
- React to lifecycle state changes
5.1 Lifecycle Library
- Part of AndroidX
- Provides classes for lifecycle awareness
- Works with activities and fragments
5.2 Lifecycle Events and Observers
| Event |
State |
Description |
| ON_CREATE |
Created |
Activity/fragment is created |
| ON_START |
Started |
Activity/fragment is visible |
| ON_RESUME |
Resumed |
Activity/fragment is in foreground |
| ON_PAUSE |
Paused |
Activity/fragment is partially obscured |
| ON_STOP |
Stopped |
Activity/fragment is no longer visible |
| ON_DESTROY |
Destroyed |
Activity/fragment is being destroyed |
5.3 LiveData
LiveData: Observable data holder class that is lifecycle-aware and keeps data updated.
Key Features:
- Automatically updates UI when data changes
- Survives configuration changes
- Prevents memory leaks
- Handles lifecycle states properly
LiveData Implementation
// 1. Define in DAO
@Query("SELECT * FROM words ORDER BY word ASC")
LiveData> getAllWords();
// 2. Use in Repository
public LiveData> getAllWords() {
return wordDao.getAllWords();
}
// 3. Use in ViewModel
public LiveData> getAllWords() {
return repository.getAllWords();
}
// 4. Observe in Activity/Fragment
wordViewModel.getAllWords().observe(this, words -> {
// Update UI when words change
adapter.setWords(words);
});
LiveData Benefits
- UI always up-to-date with latest data
- Automatic lifecycle management
- Memory leak prevention
- Configuration change handling
- Thread safety
6. Complete Architecture Flow
User (UI Layer) → Requests data
ViewModel → Provides data and handles logic
Repository → Manages data sources
Room Database → Persists data locally
SQLite → Underlying database engine
LiveData → Observes changes and updates UI
7. Quick Reference Guide
Architecture Components Summary
| Component |
Purpose |
Key Features |
| ViewModel |
Provide data to UI, survive configuration changes |
Clean UI separation, lifecycle awareness |
| Repository |
Single source of truth for data |
Data source management, clean API |
| Room Database |
SQLite abstraction layer |
Automatic code generation, compile-time checks |
| Entity |
Define database schema |
@Table annotation, column definitions |
| DAO |
Database access methods |
@Insert, @Update, @Delete, @Query annotations |
| LiveData |
Observable data with lifecycle awareness |
Automatic updates, configuration change handling |
Room Annotations Cheat Sheet
| Annotation |
Purpose |
Example |
| @Entity |
Mark class as database table |
@Entity(tableName = "words") |
| @PrimaryKey |
Define primary key |
@PrimaryKey(autoGenerate = true) |
| @ColumnInfo |
Customize column name |
@ColumnInfo(name = "word_text") |
| @NonNull |
Mark field as mandatory |
@NonNull private String word; |
| @Insert |
Insert operation |
@Insert void insert(Word word); |
| @Update |
Update operation |
@Update void update(Word word); |
| @Delete |
Delete operation |
@Delete void delete(Word word); |
| @Query |
Custom SQL query |
@Query("SELECT * FROM words") |
| @Database |
Define database class |
@Database(entities = {Word.class}, version = 1) |
Best Practices
- Always use ViewModel: Separates data management from UI
- Use Repository pattern: Centralizes data access logic
- Return LiveData from DAO: Automatic UI updates
- Handle database operations off UI thread: Use Executors
- Validate queries at compile time: Room's @Query annotation
- Use Room's compile-time checks: Catch errors early
- Handle configuration changes: LiveData and ViewModel help
- Test your architecture: Clear separation makes testing easier
8. Exam Preparation Tips
- Understand the architecture: Know the flow between components
- Memorize annotations: @Entity, @PrimaryKey, @Dao, @Query, etc.
- Practice ViewModel usage: Know how it survives configuration changes
- Understand LiveData: How it updates UI automatically
- Know Room database setup: Entity, DAO, Database classes
- Review repository pattern: Single source of truth concept
- Understand lifecycle awareness: How components react to lifecycle events
- Practice with simple examples: Start with a basic app with Room database
- Know threading: Why background threads are important for database operations
- Review past papers: Look for questions about AAC and Room
9. Summary and Key Takeaways
Android Architecture Components (AAC) provide a modern, recommended approach to building Android apps with:
- ViewModel: Survives configuration changes, provides data to UI
- Repository: Single source of truth for app data
- Room Database: Simplifies SQLite usage with automatic code generation
- LiveData: Observable data that automatically updates UI
Key Benefits:
- Clean separation of concerns
- Improved testability
- Reduced boilerplate code
- Better maintainability
- Automatic lifecycle management
- Thread-safe database operations
Architecture Flow: UI → ViewModel → Repository → Room Database → SQLite
Best Practice: Always follow the recommended app architecture for maintainable and scalable Android applications.